/* IntegrityChecker.java
 * 6 June 2012
 */
package za.ac.wits.elen7045.integrity.checks;

import jass.modern.Post;
import jass.modern.Pre;

import java.util.List;

import za.ac.wits.elen7045.integrity.checker.interfaces.IntegrityCheckingInterface;
import za.ac.wits.elen7045.integrity.checks.interfaces.IntegrityCheck;
import za.ac.wits.elen7045.integrity.checks.interfaces.IntegrityCheckReport;
import za.ac.wits.elen7045.scraper.interfaces.ScraperSessionInterface;

/**
 * Concrete implementation of the IntegrityCheckingInterface. It runs a set of Integrity checks 
 * on the scraper session data.
 * There are 3 types of standard checks done here.
 *  - Addition						: takes the Opening balance subtracts the payment recieved, adds 
 *  								  new charges, subtracts discount and subtracts deductions. Total is 
 *  								  compared to the statement total.
 *  - VAT							: Uses a configurable VAT rate, applies it to the total before VAT  
 *  			  					  and checks against statement Total.
 *  - Correlation of duplicate Data	: If a key appears more than once in the scraped data map, then it
 *  								  is compared to each other to see if the duplicates correlate.
 *  			  
 * @author Gerhard Visagie
 */
public class HellkomIntegrityChecker implements IntegrityCheckingInterface {
	
	private List<IntegrityCheck> checks;
	
	public HellkomIntegrityChecker(List<IntegrityCheck> checks){
		this.checks = checks;
	}
	
	/* (non-Javadoc)
	 * @see za.ac.wits.elen7045.integrity.checker.interfaces.IntegrityCheckingInterface#checkScrapedData(za.ac.wits.elen7045.scraper.interfaces.ScraperSessionInterface)
	 */
	@Override
	@Pre("scraperSession != null " +
			"&& scraperSession.getUrl() != null " +
			"&& scraperSession.getDateTime() > 0 " +
			"&& scraperSession != null " +
			"&& scraperSession.getDataPairs().size() > 0 " +
			"&& scraperSession.getUrl().startsWith(\"www.\") ")
	@Post("@Result == true || @Result == false")	
	public boolean checkScrapedData(ScraperSessionInterface scraperSession) {
		//we now run each check one at a time, if any one check is false, we return false 
		for(IntegrityCheck check:checks){
			//we could do more with this result, but for now this should suffice
			IntegrityCheckReport report = check.doCheck(scraperSession);
			if(!report.getStatus()){
				return false;
			}
		}
		return true;
	}	
}
